using S2Engine.Timeline;
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using S2Engine.Text;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
using S2Engine.Audio;

namespace S2Engine.Game
{
    /// <summary>
    /// Classe responsavel pelo tempo de vida do jogo desde a inicializacao
    /// </summary>
    public class S2Game : Microsoft.Xna.Framework.Game
    {
        #region Attributes
        private SceneManager scenemanager;
        private string path;
        private string title;
        private Vector2 resolution;
        private SpriteBatch batch;
        public FontManager FontManager;
        public AudioEngine AudioEngine;
        public WaveBank WaveBank;
        public SoundBank SoundBank;
        private GraphicsDeviceManager graphics;
        private ContentManager content;
        private SoundManager soundManager;
        private S2Engine.Input.Keyboard keyboard = null;


        #endregion

        #region Properties
        public S2Engine.Input.Keyboard Keyboard
        {
            get { return keyboard; }
        }

        public SoundManager SoundManager
        {
            get { return soundManager; }
        }

        public ContentManager Content
        {
            get { return content; }
        }

        public SpriteBatch Batch
        {
            get { return batch; }
            set{batch = value;}
        }
        /// <summary>
        /// Game Scene Manager
        /// </summary>
        public SceneManager SceneManager
        {
            get { return scenemanager; }
        }

        /// <summary>
        /// Caminho para a pasta raiz do Jogo
        /// </summary>
        public string Path
        {
            get { return path; }
        }

        public GraphicsDeviceManager Graphics
        {
            get { return graphics; }
        }

        /// <summary>
        /// Caminho para a pasta de Sons do Jogo
        /// </summary>
        public string SoundsPath
        {
            get { return path + "\\Sounds\\"; }
        }

        /// <summary>
        /// Caminho para a pasta de Musicas do Jogo
        /// </summary>
        public string MusicPath
        {
            get { return path + "\\Music\\"; }
        }

        /// <summary>
        /// Caminho para a pasta de Imagens do Jogo
        /// </summary>
        public string PicturesPath
        {
            get { return path + "\\Pictures\\"; }
        }

        #endregion

        #region Ctor
        /// <summary>
        /// Referencia para o objeto do Jogo
        /// </summary>
        public S2Game()
        {
            // path = System.Windows.Forms.Application.StartupPath;

            //TODO: Load GameXMLFile
            //ReadXMLFile();

            graphics = new GraphicsDeviceManager(this);
            content = new ContentManager(Services);

            scenemanager = new SceneManager(this);

            soundManager = new SoundManager();

            
            //FontManager.Fonts.Add("chars_green", new FontManager.FontInfo(Graphics.GraphicsDevice, "Images\\chars_green.png",
            //    "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789", 0, 1, 9, 16));
            //graphics.ApplyChanges();

            //SceneManager.Scenes[0].Load();
            //form.Show();
            //System.Windows.Forms.Application.Run(form);
            //FontManager.Init(this);

        }
        #endregion

        #region Methods
        protected bool InitGraphicsMode(int iWidth, int iHeight, bool bFullScreen)
        {
          // If we aren't using a full screen mode, the height and width of the window can
          // be set to anything equal to or smaller than the actual screen size.
          if (bFullScreen == false)
          {
            if ((iWidth <= GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width) 
            && (iHeight <= GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height))
            {
              graphics.PreferredBackBufferWidth = iWidth;
              graphics.PreferredBackBufferHeight = iHeight;
              graphics.IsFullScreen = bFullScreen;
              graphics.ApplyChanges();
              return true;
            }
          }
          else
          {
            // If we are using full screen mode, we should check to make sure that the display
            // adapter can handle the video mode we are trying to set. To do this, we will
            // iterate thorugh the display modes supported by the adapter and check them against
            // the mode we want to set.
            foreach (DisplayMode dm in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
            { 
              // Check the width and height of each mode against the passed values
              if ((dm.Width == iWidth) && (dm.Height == iHeight))
              {
                // The mode is supported, so set the buffer formats, apply changes and return
                graphics.PreferredBackBufferWidth = iWidth;
                graphics.PreferredBackBufferHeight = iHeight;
                graphics.IsFullScreen = bFullScreen;
                graphics.ApplyChanges(); 
                return true;
              }
            }
          }
          return false;
        }
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();

            keyboard = new S2Engine.Input.Keyboard();

            batch = new SpriteBatch(graphics.GraphicsDevice);
            
            FontManager = new FontManager(this);

            soundManager.Initialize("Audio\\AudioEngine.xgs", "Audio\\WaveBank.xwb", "Audio\\SoundBank.xsb");
            //AudioEngine = new AudioEngine("Audio\\AudioEngine.xgs");
            //WaveBank = new WaveBank(AudioEngine, "Audio\\WaveBank.xwb");
            //SoundBank = new SoundBank(AudioEngine, "Audio\\SoundBank.xsb");
            //AudioEngine = content.Load<AudioEngine>("sound");
            //WaveBank = content.Load<WaveBank>("sound");
            //SoundBank = content.Load<SoundBank>("sound");
            //AudioEngine = content.Load<AudioEngine>("Audio Engine");
            //WaveBank = content.Load<WaveBank>("Wave Bank");
            //SoundBank = content.Load<SoundBank>("Sound Bank");
        }


        /// <summary>
        /// Load your graphics content.  If loadAllContent is true, you should
        /// load content from both ResourceManagementMode pools.  Otherwise, just
        /// load ResourceManagementMode.Manual content.
        /// </summary>
        /// <param name="loadAllContent">Which type of content to load.</param>
        protected override void LoadGraphicsContent(bool loadAllContent)
        {
            if (loadAllContent)
            {
                // TODO: Load any ResourceManagementMode.Automatic content
            }

            // TODO: Load any ResourceManagementMode.Manual content
        }

        /// <summary>
        /// Unload your graphics content.  If unloadAllContent is true, you should
        /// unload content from both ResourceManagementMode pools.  Otherwise, just
        /// unload ResourceManagementMode.Manual content.  Manual content will get
        /// Disposed by the GraphicsDevice during a Reset.
        /// </summary>
        /// <param name="unloadAllContent">Which type of content to unload.</param>
        protected override void UnloadGraphicsContent(bool unloadAllContent)
        {
            if (unloadAllContent == true)
            {
                content.Unload();
            }
        }

        /// <summary>
        /// Encerra o Jogo
        /// </summary>
        private void Quit()
        {
            Dispose();
        }

        
        /// <summary>
        /// Libera os recursos consumidos pelo jogo, como imagens, sons e dispositivos de hardware
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if(SceneManager.CurrentScene != null)
                SceneManager.CurrentScene.Dispose();
        }


        //public GameTime gameTime;
        protected override void Update(GameTime gameTime)
        {
            // Allows the default game to exit on Xbox 360 and Windows
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here
            //this.gameTime = gameTime;
            base.Update(gameTime);

            keyboard.Update();
            // The time since Update was called last

            soundManager.Update();
            //AudioEngine.Update();
            // TODO: Add your game logic here
           
                

            if(SceneManager.CurrentScene != null)
            {SceneManager.CurrentScene.InputCheck();
                SceneManager.CurrentScene.Update();
            }
           

            // Let the GameComponents update
           
        }
        protected override void  Draw(GameTime gameTime)
        {
            //graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
            
            //SceneManager.CurrentScene.BeforeRender();
            
           // graphics.GraphicsDevice.BeginScene();
            
            // TODO: Add your drawing code here

 
            //OnRender(EventArgs.Empty);
            //if(SceneManager.CurrentScene != null)
            //{
                Batch.Begin(SpriteBlendMode.AlphaBlend);
                DrawScene();
                Batch.End();
                //SceneManager.CurrentScene.AfterRender();
            //graphics.GraphicsDevice.Present();
           // }

            // Let the GameComponents draw
            //DrawComponents();

            
            //graphics.GraphicsDevice.EndScene();
            

            base.Draw(gameTime);

  
            
            
        }

        protected virtual void DrawScene()
        {
            if(SceneManager.CurrentScene != null)
                SceneManager.CurrentScene.Draw();
        }
        #endregion
    }
}

